import connectRedis from 'connect-redis';
import express from 'express';
import session, { CookieOptions, SessionOptions } from 'express-session';
import createMemoryStore from 'memorystore';
import { createClient } from 'redis';

const dev = process.env.NODE_ENV !== 'production';
const local = process.env.APP_ENV === 'localhost';
/**
 * Options for express-session.
 *
 * The default server-side session storage, MemoryStore,
 * is purposely not designed for a production environment.
 * It will leak memory under most conditions, does not scale past a single process,
 * and is meant for debugging and developing.
 *
 * For details, please visit:
 * - https://github.com/expressjs/session/blob/master/README.md
 *
 * 'memorystore'
 *
 * A production compatible session store implementation for Express using lru-cache.
 *
 * For more details, please visit:
 * - https://github.com/roccomuso/memorystore/blob/master/README.md
 */
const MemoryStore = createMemoryStore(session);
const RedisStore = connectRedis(session);

// redis@v4
const redisClient = createClient({ url: process.env.REDIS_URL, legacyMode: true });
if (!local)
  redisClient.connect().catch(error => {
    console.info(`connect redis : ${process.env.REDIS_URL}`);
    console.error(error.stack);
  });

const cookieConfig: CookieOptions = {
  maxAge: dev ? 600000 : 360000000, // TTL in milliseconds (dev: 10 mins, prod: 1 hours)
  //maxAge: dev ? 600000 : 1800000, // TTL in milliseconds (dev: 10 mins, prod: 30 mins)
  httpOnly: true, // protect cookie from client
};

const sessionConfig: SessionOptions = {
  secret: 'dir-web cats', // TBD: rolling secrets
  resave: false,
  saveUninitialized: false,
  cookie: cookieConfig,
  store: 
  // local
  //   ? new MemoryStore({
  //       checkPeriod: 86400000, // prune expired entries every 24h
  //     })
  //   : 
    new RedisStore({
        client: redisClient,
      }),
};

export const createSessionMiddleware = (server: express.Application) => {
  server.use(session(sessionConfig));
};
